import http.client
import json
from urllib.parse import urldefrag
import requests
import time
import random
from datetime import datetime, timedelta
import re
import subprocess
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
import mysql.connector

# 创建连接
conn = mysql.connector.connect(
    host='rm-bp1o9x55v90h0ct6g6o.mysql.rds.aliyuncs.com',
    port='3306',
    user='wx_work',
    password='Haoxue1212',
    database='haoxue_wxwork_infor'
)

# 创建游标对象
cursor = conn.cursor()

# type_value = {"image":"图片","text":"文本","file":"文件","video":"视频","voice":"语音","link":"链接","location":"位置","contact":"联系人","groupchat":"群聊"}

type_value = {"image": "图片", "text": "文本", "file": "文件", "video": "视频"}

seq = 5909144
limit = 1000


def upload_file_to_oss(files_name, object_name):
    # 阿里云账号AccessKey拥有所有API的访问权限，风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维，请登录RAM控制台创建RAM用户
    auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())

    # 填写Bucket所在地域对应的Endpoint。以华东1（杭州）为例，Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
    endpoint = "https://oss-cn-hangzhou.aliyuncs.com"

    # 填写Endpoint对应的Region信息，例如cn-hangzhou。注意，v4签名下，必须填写该参数
    region = "cn-hangzhou"
    # 填写Bucket名称，例如examplebucket。
    bucketName = "bucket-image-shouwei"
    # 创建Bucket实例，指定存储空间的名称和Region信息。
    bucket = oss2.Bucket(auth, endpoint, bucketName, region=region)

    # 本地文件的完整路径
    local_file_path = '{}'.format(files_name)

    # 填写Object完整路径，完整路径中不能包含Bucket名称。例如exampleobject.txt。
    objectName = object_name

    # 使用put_object_from_file方法将本地文件上传至OSS
    bucket.put_object_from_file(objectName, local_file_path)

    url = "https://bucket-image-shouwei.oss-cn-hangzhou.aliyuncs.com/{}".format(objectName)
    return url


def get_token():
    url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken'
    params = {
        'corpid': 'wwdd2b1373b42aca36',
        'corpsecret': "_0fN1LJz0Z_z9z0hOiss2R94RbgRK3Wl3WbZHE4_z8Y",
    }

    # 发送GET请求并获取响应
    response = requests.get(url, params=params)

    # 检查请求是否成功
    if response.status_code == 200:
        # 请求成功，可以处理响应数据
        data = response.json()
        token = data['access_token']
        return token
    else:
        # 请求失败，可以打印出错误信息
        print(f"Error: {response.status_code}")


def get_user(token, userid):
    url = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get"
    # access_token = get_token()
    # external_userid = "wm4ru4CQAAD7AlAwn1-dtr3qUPAyCLFA"
    # 设置请求头（如果需要）
    headers = {
        'Content-Type': 'application/json',  # 如果你发送的是 JSON 数据
        # 'Authorization': 'Bearer YOUR_ACCESS_TOKEN'  # 如果需要认证
    }

    # 设置请求体（POST 请求的数据）
    data = {
        "access_token": token,
        "external_userid": userid
    }

    # 将字典转换为 JSON 字符串（如果需要）
    json_data = json.dumps(data)

    # 发送 POST 请求
    response = requests.get(url, headers=headers, params=data)

    # 检查响应状态码
    if response.status_code == 200:
        response_user = response.json()
        return response_user
    else:
        return None


def get_wx_user(wx_token, use_id):
    url = "https://qyapi.weixin.qq.com/cgi-bin/user/get"
    headers = {
        'Content-Type': 'application/json'
        # 'Authorization': 'Bearer YOUR_ACCESS_TOKEN'  # 如果需要认证
    }

    # 设置请求体（POST 请求的数据）
    data = {
        "access_token": wx_token,
        "userid": use_id,
    }

    response = requests.get(url, headers=headers, params=data)

    # 检查响应状态码
    if response.status_code == 200:
        response_user = response.json()
        return response_user
    else:
        return None


def get_group(token, group_id):
    # 设置目标 URL
    url = f'https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/get?access_token={token}'  # 设置请求头（如果需要）
    headers = {
        # 'Authorization': f'Bearer {token}',
        'Content-Type': 'application/json'  # 如果你发送的是JSON数据
    }

    # 设置请求体（POST 请求的数据）
    data = {
        "chat_id": group_id,
        "need_name": 0
    }

    # 将字典转换为 JSON 字符串（如果需要）
    json_data = json.dumps(data)

    # 发送 POST 请求
    response = requests.post(url, headers=headers, data=json_data)

    # 检查响应状态码
    if response.status_code == 200:
        # print("请求成功")
        # 解析 JSON 响应内容
        response_group = response.json()
        return response_group
        # print("响应数据:", response_data)
    else:
        return None
        # print(f"请求失败，状态码: {response.status_code}")
        # print("响应内容:", response.text)


def get_infor(seq, limit):
    infor_list = []
    # infor_dict = {}
    conn = http.client.HTTPConnection("116.62.120.28", 8888)
    payload = json.dumps({
        "seq": seq,
        "limit": limit,
        "timeout": 10
    })
    headers = {
        'Content-Type': 'application/json'
    }
    conn.request("POST", "/get_chat_data", payload, headers)
    res = conn.getresponse()
    data = res.read()
    result_data = json.loads(data.decode("utf-8")).get("data")
    if not result_data:
        return infor_list, seq
    for infor in result_data:
        send_inf = infor.get("message")
        if send_inf:
            send_user = infor.get("message").get("from", None)
            send_group = infor.get("message").get("roomid", None)
            to_user = infor.get("message").get("tolist", None)
            get_time = infor.get("message").get("msgtime", None)
            timestamp = get_time / 1000
            dt = datetime.fromtimestamp(timestamp)
            send_time = dt.strftime('%Y-%m-%d %H:%M:%S')
            msgtype = infor.get("message").get("msgtype")
            seq_name = infor.get("seq")

            if infor.get("message").get("msgtype") == "text":
                single_infor = infor.get("message").get("text").get("content")
                infor_list.append((send_user, send_group, send_time, to_user, single_infor, msgtype))
            else:
                single_infor = infor.get("message").get(msgtype)
                infor_list.append((send_user, send_group, send_time, to_user, single_infor, seq_name, msgtype))

    result_seq = result_data[-1].get("seq")
    return infor_list, result_seq


def send_group_msg(text_content, web_hook_url, mentioned_list):
    """发送微信群组机器人消息

    :param text_content: str, 消息内容
    :param web_hook_url: str, 群组机器人WebHook URL
    :param mentioned_list: list, 可选, userid列表，提醒群中的指定成员(@某个成员)，@all表示提醒所有人
    :param mentioned_mobile_list: list, 可选, 手机号列表，提醒手机号对应的群成员(@某个成员)，@all表示提醒所有人
    :return: tuple(bool, str), 返回一个元组，第一个元素为操作是否成功，第二个元素为成功或失败的消息
    """
    if mentioned_list is None:
        mentioned_list = []
    # if mentioned_mobile_list is None:
    #     mentioned_mobile_list = []

    msg = {
        "msgtype": "text",
        "text": {
            "content": text_content,
            "mentioned_list": mentioned_list,
            # "mentioned_mobile_list": mentioned_mobile_list
        }
    }

    try:
        response = requests.post(web_hook_url, json=msg)
        response.raise_for_status()  # 如果响应包含了一个HTTP错误状态码，则抛出异常
        result = response.json()

        if result.get('errmsg') == 'ok':
            return True, "Message sent successfully."
        else:
            return False, f"Failed to send message: {result.get('errmsg', 'Unknown error')}"

    except requests.exceptions.RequestException as e:
        return False, f"Request failed: {e}"


time_first = datetime.now()
token = ""
group_dict = {}
user_dict = {}
receive_dict = {}
while 1:

    try:

        data_to_insert = []

        # 第一次获取当前时间
        time_second = datetime.now()
        time_difference = time_second - time_first
        # 检查时间差是否超过一小时
        if time_difference > timedelta(hours=1):
            time_first = time_second
            # 执行相应的操作
            token = get_token()
        else:
            if token == "":
                time_first = datetime.now()
                token = get_token()
        one_infor, new_seq = get_infor(seq, limit)
        for infor in one_infor:

            user_id = infor[0]
            group_id = infor[1]
            send_msg_time = infor[2]
            to_list = infor[3]
            send_text = infor[4]
            receive_id = to_list[-1]

            if send_text == "":
                continue
            # print(len(to_list))
            user_name = ""
            group_name = ""
            receive_name = ""
            # print(user_id)

            if user_id:
                if user_id in user_dict.keys():
                    user_name = user_dict[user_id]
                else:
                    if user_id.startswith("wo") or user_id.startswith("wm"):
                        user_infor = get_user(token, user_id)
                        if user_infor:
                            if user_infor.get("errcode") == 0:
                                user_name = user_infor.get("external_contact").get("name")
                    else:
                        wx_user = get_wx_user(token, user_id)
                        user_name = wx_user.get("name")
                    user_dict[user_id] = user_name
            else:
                continue

            if group_id:
                if group_id not in group_dict.keys():
                    group_infor = get_group(token, group_id)
                    if group_infor:
                        if group_infor.get("errcode") == 0:
                            group_name = group_infor.get("group_chat").get("name")
                            group_dict[group_id] = group_name
                else:
                    group_name = group_dict[group_id]
            else:
                if receive_id in receive_dict.keys():
                    receive_name = receive_dict[receive_id]
                else:
                    receive_result = get_wx_user(token, to_list[-1])
                    if receive_result.get("errcode") == 0:
                        receive_name = receive_result.get("name")
                        receive_dict[receive_id] = receive_name
                    else:
                        if receive_id in user_dict.items():
                            receive_name = user_dict[receive_id]
                        else:
                            if receive_id.startswith("wo") or receive_id.startswith("wm"):
                                receive_infor = get_user(token, receive_id)
                                if receive_infor:
                                    if receive_infor.get("errcode") == 0:
                                        receive_name = receive_infor.get("external_contact").get("name")
                            receive_dict[receive_id] = receive_name

            sdktype = infor[-1]

            if sdktype in type_value:
                sdktype = type_value[sdktype]
                """
                1.根据 type_value 判断是否进行下列操作，存在的再进行操作
                2.此时已经换成了文本的格式
                """
                if sdktype == "图片":
                    fileid = send_text["sdkfileid"]
                    files_name = "demp.jpg"
                    subprocess.run(['./sdktools', "2", fileid, files_name])
                    down_name = str(infor[-2]) + ".jpg"
                    send_text = upload_file_to_oss(files_name, down_name)

                elif sdktype == "视频":
                    fileid = send_text["sdkfileid"]
                    files_name = "demp.mp4"
                    subprocess.run(['./sdktools', "2", fileid, files_name])
                    down_name = str(infor[-2]) + ".mp4"
                    send_text = upload_file_to_oss(files_name, down_name)
                elif sdktype == "文本":
                    send_text = send_text
                # send_text = sdkdownloadid
            else:
                continue
            print("新内容：", user_name, group_name, receive_name, send_text, send_msg_time, user_id, group_id,
                  receive_id, sdktype)

            if group_id:
                receive_id = ""
            insert_query = "INSERT INTO wxwork_infor (user_name, group_name, receive_name, send_text, send_time, user_id, group_id, receive_id, tpye) VALUES (%s, %s, %s,%s, %s, %s, %s,%s,%s)"
            data_to_insert = (
            user_name, group_name, receive_name, send_text, send_msg_time, user_id, group_id, receive_id, sdktype)
            cursor.execute(insert_query, data_to_insert)
        # 提交事务
        conn.commit()
        time.sleep(5)
        if seq <= new_seq + 500:
            time.sleep(1500)
        seq = new_seq
        print(f"seq:{seq}")
    except Exception as e:
        print(e)
        # break
        cursor.close()
        conn.close()
        error_message = str(e)
        url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=6517a496-ee52-423e-85d6-3ef57b407ff4"
        send_flag, result_infor = send_group_msg(error_message, url, [])
        conn = mysql.connector.connect(
            host='rm-bp1o9x55v90h0ct6g6o.mysql.rds.aliyuncs.com',
            port='3306',
            user='wx_work',
            password='Haoxue1212',
            database='haoxue_wxwork_infor'
        )

        # 创建游标对象
        cursor = conn.cursor()


